{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **演示0106：数组元素增删**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例1：删除元素**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**使用*np.delete*删除一维数组中的元素**  \n",
    ">* 删除指定索引位置处的元素\n",
    ">* 可以删除一个或多个位置处的元素。如果是删除多个位置，则这些位置是参照原始数组(而不是删除了某个元素之后的数组)的位置\n",
    ">* 删除后的数组是原始数组的拷贝，不会共享数据内存"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3 1 7 4 2 5 8]\n",
      "[3 7 4 2 5 8]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "a = np.array([3, 1, 7, 4, 2, 5, 8])\n",
    "b = np.delete(a, 1)    # 删除索引1号位置处的元素\n",
    "print(a)    # a不会发生变化\n",
    "print(b)    # b存放了删除后的结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 5 8]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([3, 1, 7, 4, 2, 5, 8])\n",
    "b = np.delete(a, [0,2,3])    # 删除原数组中索引为0,2,3的元素\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **删除二维数组中的元素**  \n",
    ">* 如果不指定*axis*，则将二维数组展成一维数组，然后删除指定位置的元素。返回的数组已经变成了一维数组\n",
    ">* 设置*axis=0*，表示沿竖直方向(行索引增加方向)删除指定索引位置的元素，此时实际上删除的是一行\n",
    ">* 设置*axis=1*，表示沿水平方向(列索引增加方向)删除指定索引位置的元素，此时实际上删除的是一列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  3  4  5  6  7  8  9 10 11 12 13 14 15]\n",
      "[ 1  3  5  7  8  9 10 11 12 13 14 15]\n"
     ]
    }
   ],
   "source": [
    "# 不指定axis\n",
    "a = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])\n",
    "b = np.delete(a, 1)\n",
    "c = np.delete(a, [1,3,5])\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 6  7  8  9 10]\n",
      " [11 12 13 14 15]]\n",
      "[[11 12 13 14 15]]\n"
     ]
    }
   ],
   "source": [
    "# 删除行\n",
    "a = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])\n",
    "b = np.delete(a, 0, axis=0)    # 删除下标索引为0的行\n",
    "print(b)\n",
    "c = np.delete(a, [0,1], axis=0)    # 删除下标索引为0和1的行\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 2  3  4  5]\n",
      " [ 7  8  9 10]\n",
      " [12 13 14 15]]\n",
      "[[ 3  4  5]\n",
      " [ 8  9 10]\n",
      " [13 14 15]]\n"
     ]
    }
   ],
   "source": [
    "# 删除列\n",
    "a = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])\n",
    "b = np.delete(a, 0, axis=1)    # 删除下标索引为0的列\n",
    "print(b)\n",
    "c = np.delete(a, [0,1], axis=1)    # 删除下标索引为0和1的列\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **实验2：追加元素**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**在一维数组末尾追加元素**  \n",
    ">* *np.append*方法\n",
    ">* 可以追加1个或多个元素\n",
    ">* 追加操作不会修改原来的数组，而是拷贝生成一个新数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5]\n",
      "[1 2 3 4 5 6]\n",
      "[1 2 3 4 5 6 7 8]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1,2,3,4,5])\n",
    "b = np.append(a, 6)\n",
    "c = np.append(a, [6,7,8])\n",
    "print(a)\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**二维数组末尾追加元素**  \n",
    ">* 如果不指定*axis*，则将二维数组展成一维数组，并在最后追加数据\n",
    ">* 设置*axis=0*，可追加行。应确保追加的数据与原始数据具有相同的列数\n",
    ">* 设置*axis=1*，可追加列。应确保追加的数据与原始数据具有相同的行数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 1 2 2 3 3 4]\n",
      "[1 1 2 2 3 3 4 5 6]\n"
     ]
    }
   ],
   "source": [
    "# 不指定axis\n",
    "a = np.array([[1, 1], [2, 2], [3, 3]])\n",
    "b = np.append(a, 4)    # 变成一维数组\n",
    "c = np.append(a, [4,5,6])\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 1]\n",
      " [2 2]\n",
      " [3 3]\n",
      " [4 4]\n",
      " [5 5]]\n",
      "[[1 1]\n",
      " [2 2]\n",
      " [3 3]\n",
      " [4 4]]\n"
     ]
    }
   ],
   "source": [
    "# 追加行\n",
    "a = np.array([[1, 1], [2, 2], [3, 3]])\n",
    "b = np.append(a, np.array([[4,4],[5,5]]), axis=0)    # 追加2行数据。每行数据的列数应与原始数组匹配\n",
    "c = np.append(a, np.array([[4,4]]), axis=0)    # 即使只追加1行，也应写成(1,2)二维数组维度的形式\n",
    "#d = np.append(a, np.array([4,4]), axis=0)   # 错误。不满足二维数组维度形式\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 1 4]\n",
      " [2 2 4]\n",
      " [3 3 4]]\n",
      "[[1 1 4 5]\n",
      " [2 2 4 5]\n",
      " [3 3 4 5]]\n"
     ]
    }
   ],
   "source": [
    "# 追加列\n",
    "a = np.array([[1, 1], [2, 2], [3, 3]])\n",
    "b = np.append(a, np.array([[4],[4],[4]]), axis=1)    # 追加1列数据。每列数据的行数应与原始数组匹配\n",
    "c = np.append(a, np.array([[4, 5],[4, 5],[4, 5]]), axis=1)    # 追加2列数据。每列数据的行数应与原始数组匹配\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**使用*np.c_[ ]*操作符在二维数组开头或末尾添加新列**  \n",
    ">* 以一维数组的方式提供要添加的新列数据\n",
    ">* 在机器学习的特征数组预处理过程中，经常需要在矩阵的开头或结尾追加一个新列，可以使用此种方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4  5  1]\n",
      " [ 6  7  8  9 10  1]\n",
      " [11 12 13 14 15  1]]\n",
      "[[ 1.  1.  2.  3.  4.  5.]\n",
      " [ 1.  6.  7.  8.  9. 10.]\n",
      " [ 1. 11. 12. 13. 14. 15.]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])\n",
    "b = np.c_[a, np.array([1,1,1])]    # 在原始数组末尾添加一个全为1的列。该列的行数应与原始数组匹配\n",
    "# b = np.c_[a, np.ones(len(a))]    # 使用np.ones(len(a))可直接生成与原始数组行数匹配的数组\n",
    "c = np.c_[np.ones(len(a)), a]    # 在原始数组开头添加一个全为1的列\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例3：插入元素**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**在一维数组指定位置插入元素**  \n",
    ">* *np.insert*方法\n",
    ">* 可以插入一个或多个元素\n",
    ">* 不会修改原始数组，而是生成新的拷贝数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1 10 20  2  3  4  5]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1,2,3,4,5])\n",
    "b = np.insert(a, 1, [10,20])\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**在二维数组中插入元素**  \n",
    ">* 如果不指定*axis*，则将二维数组展成一维数组，并在指定位置插入元素\n",
    ">* 设置*axis=0*，可插入行。应确保插入的数据与原始数据具有相同的列数\n",
    ">* 设置*axis=1*，可插入列。应确保插入的数据与原始数据具有相同的行数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 4 1 2 2 3 3]\n",
      "[1 4 5 6 1 2 2 3 3]\n"
     ]
    }
   ],
   "source": [
    "# 不指定axis\n",
    "a = np.array([[1, 1], [2, 2], [3, 3]])\n",
    "b = np.insert(a, 1, 4)    # 在位置索引1处插入元素4\n",
    "c = np.insert(a, 1, [4,5,6])    # 在位置索引1处插入元素4,5,6\n",
    "print(b)\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 1]\n",
      " [4 4]\n",
      " [5 5]\n",
      " [2 2]\n",
      " [3 3]]\n",
      "[[1 1]\n",
      " [2 2]\n",
      " [3 3]\n",
      " [4 4]]\n"
     ]
    }
   ],
   "source": [
    "# 插入行\n",
    "a = np.array([[1, 1], [2, 2], [3, 3]])\n",
    "b = np.insert(a, 1, np.array([[4, 4], [5, 5]]), axis=0)    # 在行索引1号位插入两行。每行的列数必须与原始数组一致\n",
    "c = np.insert(a, len(a), np.array([[4,4]]), axis=0)    # len(a)实际上相当于在末尾插入行\n",
    "d = np.insert(a, len(a), [4,4], axis=0)    # insert函数支持直接给出一维数组作为要插入的行或列，不必转换成二维数组格式\n",
    "print(b)\n",
    "print(c)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  0  1]\n",
      " [ 2  5  2]\n",
      " [ 3 10  3]]\n",
      "[[1 5 1]\n",
      " [2 5 2]\n",
      " [3 5 3]]\n"
     ]
    }
   ],
   "source": [
    "# 插入列\n",
    "a = np.array([[1, 1], [2, 2], [3, 3]])\n",
    "b = np.insert(a, 1, [0,5,10], axis=1)    # insert函数支持直接给出一维数组作为要插入的行或列，不必转换成二维数组格式\n",
    "c = np.insert(a, 1, 5, axis=1)    #  insert函数自动将要插入的数据(5)转换成具有3个元素的一维数组，从而可以作为一列数据插入\n",
    "print(b)\n",
    "print(c)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
